package ru.myrtle.umf.query.condition.object;

import ru.myrtle.umf.UClass;
import ru.myrtle.umf.UObject;

public class UObjectContainmentCondition extends UObjectCondition {

    public static enum Relation {

        PARENT {
            @Override
            boolean isSatisfied(UObject object, UObject container) {
                return object.uContainer() == container;
            }
        },

        ANCESTOR {
            @Override
            boolean isSatisfied(UObject object, UObject container) {
                for (UObject c = object.uContainer(); c != null; c = c.uContainer()) {
                    if (c == container) {
                        return true;
                    }
                }

                return false;
            }
        },

        NEAREST_ANCESTOR{
            @Override
            boolean isSatisfied(UObject object, UObject container) {
                UClass containerClass = container.uClass();

                for (UObject c = object.uContainer(); c != null; c = c.uContainer()) {
                    UClass t  = c.uClass();

                    if (t == containerClass) {
                        return c == container;
                    }
                }

                return false;
            }
        };

        abstract boolean isSatisfied(UObject object, UObject container);
    }

    private final UObject container;
    private final Relation relation;

    public UObjectContainmentCondition(UObject container, Relation relation) {
        this.container = container;
        this.relation = relation;
    }

    @Override
    protected boolean isSatisfiedImpl(UObject object) {
        return relation.isSatisfied(
                object, container
        );
    }
}
